#pragma once

#include <iostream>
#include <string>
#include <vector>
#include <functional>
#include <pthread.h>

using namespace std;


/*
 * 线程类 `Thread` 使用说明：
 *
 * 该类是对线程的封装，支持绑定自定义任务函数和传递参数。
 *
 * 主要功能：
 * 1. 启动线程并执行绑定的任务函数。
 * 2. 支持传递自定义数据到任务函数。
 * 3. 提供线程名称便于区分和调试。
 * 4. 支持线程启动 (`Start`) 和阻塞等待结束 (`Join`)。
 *
 * 模板参数：
 * - `T`：任务函数所需的数据类型。
 *
 * 构造函数：
 * - `Thread(const string &threadname, func_t<T> func, T &data)`
 *   - `threadname`: 线程名称，便于标识。
 *   - `func`: 任务函数，格式为`std::function<void(T&)>`。
 *   - `data`: 传递给任务函数的参数。
 *
 * 成员函数：
 * - `bool Start()`: 启动线程，返回是否成功。
 * - `bool Join()`: 阻塞等待线程结束，返回是否成功。
 * - `string ThreadName()`: 获取线程名称。
 * - `bool IsRunning()`: 判断线程是否正在运行。
 *
*/

// 线程封装
template<class T>
using func_t = function<void(T&)>;

template<class T>
class Thread
{
public:
    Thread(const string &threadname, func_t<T> func, T &data)
    : _tid(0), _threadname(threadname), _isrunning(false), _func(func), _data(data)
    {}
    // 由于成员函数默认会带上一个this指针，不符合回调函数的格式，所以要加上static
    static void *ThreadRoutine(void *args)
    {
        Thread *ts = static_cast<Thread *>(args);
        ts->_func(ts->_data);
        return nullptr;
    }
    string ThreadName()
    {
        return _threadname;
    }
    bool Start()
    {
        int n = pthread_create(&_tid, nullptr, ThreadRoutine, this);
        if(n == 0)
        {
            _isrunning = true;
            return true;
        }
        else return false;
    }
    bool Join()
    {
        if(!_isrunning) return true;
        int n = pthread_join(_tid, nullptr);
        if(n == 0)
        {
            _isrunning = false;
            return true;
        }
        return false;
    }
    bool IsRunning()
    {
        return _isrunning;
    }
    ~Thread()
    {}
private:
    pthread_t _tid;
    string _threadname;
    bool _isrunning;
    func_t<T> _func;    
    T _data;
};
